import React, {useEffect, useMemo, useState} from "react";
import {createEditor, Descendant, Editor,  Transforms} from "slate";
import * as Y from 'yjs'
import {WebsocketProvider} from "y-websocket";
import {Editable, Slate, withReact} from "slate-react";
import {withYjs, YjsEditor,withCursors} from "@slate-yjs/core";
import {useSearchParams} from "react-router-dom";
import { useCookies} from "react-cookie";
import {Cursors} from "../Cursors";
import {useSelector} from "react-redux";
// const initialValue = [{
//     children: [{ text: '新的内容测试' }],
// }]
interface CollaborativeEditorProps{
    initialValue:Descendant[]
}
const randomHexColor=()=>{ //随机生成十六进制颜色
    var hex = Math.floor(Math.random() * 16777216).toString(16); //生成ffffff以内16进制数
    while (hex.length < 6) { //while循环判断hex位数，少于6位前面加0凑够6位
        hex = '0' + hex;
    }
    return '#' + hex; //返回‘#'开头16进制颜色
}
const CollaborativeEditor:React.FC<CollaborativeEditorProps>=({initialValue})=>{
    const [connected, setConnected] = useState(false);
    const [sharedType, setSharedType] = useState<Y.XmlText>();
    const [provider, setProvider] = useState<WebsocketProvider>();
    const [searchParams,serSearchParams]=useSearchParams();
    const [cookies, setCookie, removeCookie] = useCookies(['CSESSIONID']);
    useEffect(() => {
        const yDoc = new Y.Doc()
        const sharedDoc = yDoc.get('slate', Y.XmlText)
        const articleId=searchParams.get("articleId")||"";
        // Set up your Yjs provider. This line of code is different for each provider.
        const yProvider = new WebsocketProvider('ws://localhost:5700', articleId||"", yDoc,
            {
                'params':{
                    "JSESSIONID":cookies.CSESSIONID,
                    "articleId":articleId
                }
            })
        const awareness=yProvider.awareness;
        const color=randomHexColor();
        awareness.setLocalStateField('user', {
            // Define a print name that should be displayed
            name: 'Emmanuelle Charpentier',
            // Define a color that should be associated to the user:
            color: color // should be a hex color
        })
        yProvider.on('sync', setConnected)
        setSharedType(sharedDoc)
        setProvider(yProvider)
        return () => {
            yDoc?.destroy()
            yProvider?.off('sync', setConnected)
            yProvider?.destroy()
        }
    }, [])
    if (!connected || !sharedType || !provider) {
        return <div>Loading…</div>
    }
    return <SlateEditor initialValue={initialValue} shareType={sharedType} provider={provider}/>;
}



interface SlateEditorProps{
    initialValue:Descendant[],
    shareType: Y.XmlText,
    provider: WebsocketProvider,
}
const SlateEditor:React.FC<SlateEditorProps>=({initialValue,shareType,provider})=>{
    //@ts-ignore
    const userInfo=useSelector((state)=>state.user.userInfo);

    const editor = useMemo(()=>{
        const editor= withYjs(createEditor(),shareType)
        withCursors(editor,provider.awareness,
            {data: {
                name: userInfo.userName,
                color: '#00ff00',
            },});
        const e=withReact(editor);
        const {normalizeNode}=e;
        // shareType.insert(0, "my link", { a: { href: 'https://..' } })

        e.normalizeNode=entry => {
            const [node]=entry;
            if(!Editor.isEditor(node)||node.children.length>0){
                return normalizeNode(entry);
            }
            Transforms.insertNodes(editor,initialValue,{at:[0]});
        }
        return e;
    },[]);
    useEffect(() => {
        YjsEditor.connect(editor)
        return () => YjsEditor.disconnect(editor)
    }, [editor])
    return (
        <Slate editor={editor} initialValue={initialValue}>
            <Cursors>
                <Editable/>
            </Cursors>

        </Slate>
    );
}








export default CollaborativeEditor;

